#if !defined(BASIC_TYPES_H)
#define BASIC_TYPES_H
#include <Config.h>

#ifdef WIN32

#ifndef BASIC_INTEGER_TYPE_DEFINED
#define BASIC_INTEGER_TYPE_DEFINED

typedef char			int8_t;
typedef unsigned char	u_int8_t;
typedef short			int16_t;
typedef unsigned short	u_int16_t;
typedef int				int32_t;
typedef unsigned int	u_int32_t;
typedef __int64			int64_t;
typedef unsigned __int64 u_int64_t;

#endif // !defined(BASIC_INTEGER_TYPE_DEFINED)

const int8_t INT8_MIN = -128;
const int8_t INT8_MAX = 0x7F;
const u_int8_t UINT8_MIN = 0;
const u_int8_t UINT8_MAX = 0xFF;
const int16_t INT16_MIN = -32768;
const int16_t INT16_MAX = 0x7FFF;
const u_int16_t UINT16_MIN = 0;
const u_int16_t UINT16_MAX = 0xFFFF;
const int32_t INT32_MIN = 0x80000000;
const int32_t INT32_MAX = 0x7FFFFFFF;
const u_int32_t UINT32_MIN = 0;
const u_int32_t UINT32_MAX = 0xFFFFFFFF;
const int64_t INT64_MIN = 0x8000000000000000LL;
const int64_t INT64_MAX = 0x7FFFFFFFFFFFFFFFLL;
const u_int64_t UINT64_MIN = 0;
const u_int64_t UINT64_MAX = 0xFFFFFFFFFFFFFFFFULL;

#else 
#include <sys/types.h>
const int8_t INT8_MIN = 0x80;
const int8_t INT8_MAX = 0x7F;
const u_int8_t UINT8_MIN = 0;
const u_int8_t UINT8_MAX = 0xFF;
const int16_t INT16_MIN = 0x8000;
const int16_t INT16_MAX = 0x7FFF;
const u_int16_t UINT16_MIN = 0;
const u_int16_t UINT16_MAX = 0xFFFF;
const int32_t INT32_MIN = 0x80000000;
const int32_t INT32_MAX = 0x7FFFFFFF;
const u_int32_t UINT32_MIN = 0;
const u_int32_t UINT32_MAX = 0xFFFFFFFF;
const int64_t INT64_MIN = 0x8000000000000000LL;
const int64_t INT64_MAX = 0x7FFFFFFFFFFFFFFFLL;
const u_int64_t UINT64_MIN = 0;
const u_int64_t UINT64_MAX = 0xFFFFFFFFFFFFFFFFULL;

#endif // defined(WIN32)


template <typename T>
inline void ConvertByteOrder(T& value)
{
	int left = 0, right = sizeof(value) - 1;
	u_int8_t* ptr = (u_int8_t*)&value;
	char c;
	while(left < right)
	{
		c = ptr[left]; ptr[left] = ptr[right]; ptr[right] = c;
		++left;
		--right;
	}
	return;
}

// convert host byte order to big endian
template <typename T>
inline void ToBigEndian(T& value)
{
	u_int16_t test = 0x00FF;
	if(((u_int8_t*)&test)[0] == 0xFF)		// host byte order is little endian
	{
		ConvertByteOrder(value);
	}
	return;
}
// convert from big endian to host byte order 
template <typename T>
inline void FromBigEndian(T& value)
{
	u_int16_t test = 0x00FF;
	if(((u_int8_t*)&test)[0] == 0xFF)		// host byte order is little endian
	{
		ConvertByteOrder(value);
	}
	return;
}
// convert host byte order to little endian
template <typename T>
inline void ToLittleEndian(T& value)
{
	u_int16_t test = 0x00FF;
	if(((u_int8_t*)&test)[0] == 0x00)		// host byte order is big endian
	{
		ConvertByteOrder(value);
	}
	return;
}
// convert from little endian to host byte order
template <typename T>
inline void FromLittleEndian(T& value)
{
	u_int16_t test = 0x00FF;
	if(((u_int8_t*)&test)[0] == 0x00)		// host byte order is big endian
	{
		ConvertByteOrder(value);
	}
	return;
}

#endif // !defined(BASIC_TYPES_H)


